package interfaces;

import interfaces.superWidgets.InterfaceButton;
import interfaces.superWidgets.MoneyListener;
import interfaces.superWidgets.StaticContent;
import logic.common.player.Player;
import logic.nodes.nodeSettings.Settings;
import logic.nodes.nodeSettings.upgrades.UpgradableSettings;
import main.InitGame;
import main.listeners.listenerClasses.LanguageListener;
import fileHandling.language.Lang;
import fileHandling.language.LanguageLoader;
import fileHandling.language.interfaces.SpawnMenuText;

import org.fenggui.Button;
import org.fenggui.binding.render.ImageFont;
import org.fenggui.event.ButtonPressedEvent;
import org.fenggui.event.IButtonPressedListener;
import org.fenggui.event.mouse.IMouseListener;
import org.fenggui.event.mouse.MouseClickedEvent;
import org.fenggui.event.mouse.MouseDoubleClickedEvent;
import org.fenggui.event.mouse.MouseDraggedEvent;
import org.fenggui.event.mouse.MouseEnteredEvent;
import org.fenggui.event.mouse.MouseExitedEvent;
import org.fenggui.event.mouse.MouseMovedEvent;
import org.fenggui.event.mouse.MousePressedEvent;
import org.fenggui.event.mouse.MouseReleasedEvent;
import org.fenggui.event.mouse.MouseWheelEvent;
import org.fenggui.util.Color;

public class PropertyWidget extends StaticContent implements MoneyListener {
	
	private Lang description;
	private int propContentX, buttonX, propContentWidth, buttonWidth;
	private int availableMoney, upgradeCosts;
	private PropertyContent propContent;
	private UpgradableSettings properties;
	private String[] keys;
	private boolean upgradeInitialized, fullyUpgraded, upgradeEnabled;
	private InterfaceButton upgradeButton;
	private Settings maxValues;
	private float maxValue;
	private IButtonPressedListener upgradeListener;
	private Player player;
	
	public PropertyWidget(Lang description, int width, int height, UpgradableSettings properties, 
			String[] keys, Settings maxValues, Player player) {
		this(description, width, height, properties, keys, maxValues, PropertyContent.Mode.LEFT, player);
	}
	
	public PropertyWidget(Lang description, int width, int height, UpgradableSettings properties, 
			String[] keys, Settings maxValues, PropertyContent.Mode mode, Player player) {
		super(width, height, 0, 0);
		this.description = description;
		this.properties = properties;
		this.keys = keys;
		this.maxValues = maxValues;
		this.player = player;
		
		propContentX = 0;
		propContentWidth = width / 3 * 2;
		buttonX = propContentWidth;
		buttonWidth = width / 3;
		
		initPropertyContent(mode);
		
		layout();
		
		InitGame.get().addLanguageListener(new LanguageListener() {
			@Override
			public void languageChanged() {
				changeLanguage();
			}
		});
	}
	
	private void initPropertyContent(PropertyContent.Mode mode) {
		propContent = new PropertyContent(propContentWidth, height, propContentX, 0, description, mode);
		addWidget(propContent);
		
		initValues(true);
	}
	
	private void initValues(boolean initMaxValues) {
		if(properties.isFullyUpgraded(keys[0])) fullyUpgraded = true;
		
		upgradeCosts = 0;
		
		maxValue = 0f;
		float value = 0f;
		float upgradeValue = 0f;
		for(String key : keys) {
			value += Float.valueOf(properties.getValueOf(key)).floatValue();
			String upgradeString = properties.getValueOfLevel(key, properties.getLevelOf(key) + 1);
			if(upgradeString != null) upgradeValue += Float.valueOf(upgradeString).floatValue();
			if(initMaxValues) maxValue += Float.valueOf(maxValues.getValueOf(key)).floatValue();
			upgradeCosts += properties.getUpgradeCost(key);
		}
		
		propContent.setValue(value);
		propContent.setUpgradeValue(Math.abs(upgradeValue - value));
		if(initMaxValues) propContent.setMaxValue(maxValue);
	}
	
	public void initUpgrade(boolean init) {
		if(upgradeInitialized && !init) removeWidget(upgradeButton);
		else if(!upgradeInitialized && init) initButtons();
		upgradeInitialized = init;
		upgradeEnabled = upgradeInitialized;
	}
	
	public void initButtons() {
		upgradeButton = new InterfaceButton(GUISource.middleFont);
		upgradeListener = new IButtonPressedListener() {
			@Override
			public void buttonPressed(ButtonPressedEvent e) {
				player.spendMoney(upgradeCosts);
				upgrade();
				updateButton();
			}
		};
		upgradeButton.addButtonPressedListener(upgradeListener);
		upgradeButton.addMouseListener(new IMouseListener() {
			@Override
			public void mouseEntered(MouseEnteredEvent mouseEnteredEvent) {
				propContent.showUpgrade(true);
			}
			
			@Override
			public void mouseClicked(MouseClickedEvent mouseClickedEvent) {}
			
			@Override
			public void mouseDoubleClicked(MouseDoubleClickedEvent mouseDoubleClickedEvent) {}
			
			@Override
			public void mouseDragged(MouseDraggedEvent mouseDraggedEvent) {}
			
			@Override
			public void mouseExited(MouseExitedEvent mouseExited) {
				propContent.showUpgrade(false);
			}

			@Override
			public void mouseMoved(MouseMovedEvent mouseMovedEvent) {}
			
			@Override
			public void mousePressed(MousePressedEvent mousePressedEvent) {}
			
			@Override
			public void mouseReleased(MouseReleasedEvent mouseReleasedEvent) {}
			
			@Override
			public void mouseWheel(MouseWheelEvent mouseWheelEvent) {}
		});
		
		updateMoney(player.getMoney());
		upgradeButton.setXY(buttonX, 0);
		upgradeButton.setSize(buttonWidth, height);
		addWidget(upgradeButton);
	}
	
	public void upgrade() {
		float value = 0f;
		float upgradeValue = 0f;
		upgradeCosts = 0;
		
		for(String key : keys) {
			properties.upgrade(key);
			value += Float.valueOf(properties.getValueOf(key)).floatValue();
			String upgradeString = properties.getValueOfLevel(key, properties.getLevelOf(key) + 1);
			if(upgradeString != null) upgradeValue += Float.valueOf(upgradeString).floatValue();
			upgradeCosts += properties.getUpgradeCost(key);
		}
		
		propContent.setValue(value);
		propContent.setUpgradeValue(Math.abs(upgradeValue - value));
		
		fullyUpgraded = properties.isFullyUpgraded(keys[0]);
		propContent.showUpgrade(false);
		layout();
	}
	
	public void setProperties(UpgradableSettings props) {
		properties = props;
		initValues(false);
		updateMoney(player.getMoney());
		propContent.showUpgrade(false);
	}
	
	public void setUpgradeButtonListener(IButtonPressedListener listener) {
		upgradeButton.removeButtonPressedListener(upgradeListener);
		upgradeListener = listener;
		upgradeButton.addButtonPressedListener(upgradeListener);
	}
	
	public Button getUpgradeButton() { return upgradeButton; }
	
	public IButtonPressedListener getUpradeListener() { return upgradeListener;  }
	
	public Lang getDescription() { return description; }
	
	public void setDescriptionFont(ImageFont font) { propContent.setTextFont(font); }
	
	public void setUpgradeButtonFont(ImageFont font) { GUISource.setFont(upgradeButton, font); }
	
	public float getUpgradeCosts() { return upgradeCosts; }
	
	public void updateButton() {
		if(upgradeButton == null) return;
		upgradeButton.setText(LanguageLoader.get(SpawnMenuText.Upgrade) + "(" +  upgradeCosts + ")");
		upgradeButton.setEnabled(false);
		GUISource.setTextColor(upgradeButton, Color.WHITE);
		if(availableMoney >= upgradeCosts && !fullyUpgraded) upgradeButton.setEnabled(true);
		else GUISource.setTextColor(upgradeButton, Color.RED);
		
		if(fullyUpgraded || !upgradeEnabled) removeWidget(upgradeButton);
		else addWidget(upgradeButton);
	}
	
	@Override
	public void updateMoney(int newMoney) {
		availableMoney = newMoney;
		fullyUpgraded = properties.isFullyUpgraded(keys[0]);
		updateButton();
	}
	
	public void enableUpgrade(boolean enable) { upgradeEnabled = enable; }
	
	public boolean upgradeIsEnabled() { return upgradeEnabled; }
	
	public boolean upgradeButtonEnabled() { return upgradeButton.isEnabled(); }
	
	public void changeLanguage() {
		updateButton();
	}
}